/**
 * 文件名：AbstractProcess.java
 *
 * 创建人：Elvin Zhao - 279152260@qq.com
 *
 * 创建时间：2019年1月2日 下午3:17:12
 *
 * 版权所有：FNII
 */
package com.z100h.supplychain.core.process;

import java.util.List;

import org.springframework.util.CollectionUtils;

import com.jeeplus.core.facade.FacadeException;
import com.z100h.supplychain.core.Evidence;
import com.z100h.supplychain.core.EvidenceLockState;
import com.z100h.supplychain.core.EvidenceState;
import com.z100h.supplychain.core.ResourceLockState;
import com.z100h.supplychain.core.ResourceStockoutLockState;

/**
 * 
 * [描述信息：说明类的基本功能]
 *
 * @author Elvin Zhao - 279152260@qq.com
 * @version 1.0 Created on 2019年1月2日 下午7:24:18
 */
public abstract class AbstractWithdrawProcess<T extends Evidence> extends BaseProcess {

	/**
	 * 创建 单据
	 * 1.evidence 主表
	 * 2.evidenceDetail* 单据详情
	 * 
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年1月2日 下午3:29:43
	 */
	protected abstract String createEvidence(T evidence, EvidenceState evidenceState);

	/**
	 * 更具单据修改资源
	 * 
	 * @param evidenceId
	 * @param resourceIds
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年1月2日 下午4:59:52
	 */
	protected abstract void changeResourceWithEvidence(final T evidence, final List<String> resourceIds);

	/**
	 * 0.锁 资源
	 * 1.创建 单据
	 * 2.关联 单据，资源
	 * 3.完成 单据
	 * 4.解锁 资源
	 * 
	 * @param resourceIds
	 * @throws Throwable
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年1月2日 下午4:16:53
	 */
	public void process(final List<String> resourceIds, T evidence) throws FacadeException {

		List<String> lockedResourceIds = checkResource(resourceIds, EvidenceLockState.UNLOCK,ResourceStockoutLockState.LOCK);

		if (CollectionUtils.isEmpty(lockedResourceIds)) {
			Boolean resourceLockState = lockResource(resourceIds, EvidenceLockState.LOCK);

			if (resourceLockState) {

				String evidenceId = createEvidence(evidence, EvidenceState.CREATE);

				associateEvidenceWithResource(evidenceId, resourceIds);

				changeResourceWithEvidence(evidence, resourceIds);

				finishEvidence(evidenceId, EvidenceState.FINISH);

				Boolean resourceUnlockState = unlockResource(resourceIds, EvidenceLockState.UNLOCK,ResourceStockoutLockState.UNLOCK);

				if (resourceUnlockState) {

					resourceLogging(evidenceId, ResourceLockState.UNLOCK);

				} else {
					throw new FacadeException("失败：资源解锁异常！");
				}
			} else {
				throw new FacadeException("失败：资源锁定异常！");
			}
		} else {
			throw new FacadeException("失败：资源存在锁定状态！");
		}
	}

}
